/*
 * Copyright (C) 2024, Ingenic Semiconductor Co.,Ltd.
 * Author: Keven <keven.ywhan@ingenic.com>
 */

#ifndef __CCU_H__
#define __CCU_H__

#include <common.h>

void inline flush_l1cache_all()
{
	asm volatile("fence.i\n":::"memory");
}

unsigned long inline virt_to_phys(void * vaddr)
{
	return (unsigned long)((unsigned long)vaddr & 0x7fffffff);
}

void inline set_l2cache_size(unsigned int d)
{
	unsigned int val;

	val = readl((CCU_BASE + CCU_MSCR));
	val &= ~(7 << 10);
	val |= ((d & 7) << 10);
	writel(val, (CCU_BASE + CCU_MSCR));
}

unsigned int inline get_current_l2cache_size()
{
	unsigned int val;

	val = readl((CCU_BASE + CCU_MSCR));
	val = (val >> 10) & 7;

	return val;
}

unsigned int inline get_l2cache_maxsize()
{
	unsigned int val;

	val = readl(CCU_BASE + CCU_CCR);
	val = (val>>16) & 0x7;

	return val;
}

void inline set_oram_attr(unsigned int d)
{
	unsigned int val;

	val = readl((CCU_BASE + CCU_CFCR));
	val &= ~(3 << 1);
	val |= (d << 1);
	writel(val, (CCU_BASE + CCU_CFCR));
}

unsigned int inline get_oram_attr()
{
	unsigned int val;

	val = readl((CCU_BASE + CCU_CFCR));
	val = (val >> 1) & 3;

	return val;
}


void inline set_reset_entry(unsigned long addr)
{
	writel(addr, (CCU_BASE + CCU_PER));
}

void inline start_harts(int hartmapval)
{
	unsigned int val;

	val = readl((CCU_BASE + CCU_CSRR));
	val &= ~(hartmapval);
	writel(val, (CCU_BASE + CCU_CSRR));
}

/*This func return val bequal total hart num - 1*/
unsigned int inline get_hart_num()
{
	unsigned int val;

	val = readl((CCU_BASE + CCU_CCR)) & 0xffff;

	return val;
}

//{{{ CFCR:BASE+0x0fe0(0x12200fe0):
/* Content                     | BIT
 * ---------------------------------
 * IFU : dis_jbuf              | 18
 * IFU : dis_ncl               | 17
 * IFU : ifu_way_allocate      | 16
 * IFU : ifu_way_ht            | 15
 * IFU : ifu_way_num           | 14:13
 * SIMD: dis_smt_simd          | 12
 * SIMD: en_simd_interleaving  | 11
 * CCU : en_sre0_wr            | 10
 * IU  : dis_basecache_confirm | 9
 * IU  : dis_is_done           | 8
 * IU  : dis_pc_valid          | 7
 * IU  : dis_fuse              | 6
 * IU  : dis_dc_miss_gate      | 5
 * IFU : dis_loop_gate         | 4
 * IFU : dis_simple_loop       | 3
 * MMU : dis_ftlb              | 2
 * MMU : dis_mc                | 1
 * CSR : en_timer              | 0
 */

//{{{ MSCR:BASE+0x0060(0x12200060):
/* Content                     | BIT
 * ---------------------------------
 * L2C : dis_trust             | 4
 */

void inline ccu_dis_trust()
{
	unsigned int val;

	val  = readl((CCU_BASE + CCU_MSCR));
	val &= ~(1 << 4);
	val |= (1 << 4);
	writel(val, (CCU_BASE + CCU_MSCR));
}

void inline ccu_dis_ifu_simple_loop()
{
	unsigned int val;

	val  = readl((CCU_BASE + CCU_CFCR));
	val &= ~(0x18);
	val |= (0x18);
	writel(val, (CCU_BASE + CCU_CFCR));
}

unsigned int inline read_ccu_cfcr()
{
	unsigned int val = 0;

	val = readl((CCU_BASE + CCU_CFCR));

	return val;
}

unsigned int inline read_ccu_mscr()
{
	unsigned int val = 0;

	val = readl((CCU_BASE + CCU_MSCR));

	return val;
}

#endif
